/* Copyright  2009
   @Author
   Richard Changde Yin            e-mail yinchangde@hotmail.com

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
   
/**
 *@filename:  quarter.cc
 */ 
#include "server_includes.h"
#include CSTDINT_H
#include "temporal.h"
#include "error.h"
#include "function/time/quarter.h"

int64_t Item_func_quarter::val_int()
{
  assert(fixed);

  if (args[0]->is_null())
  {
    /* For NULL argument, we return a NULL result */
    null_value= true;
    return 0;
  }

  /* Grab the first argument as a DateTime object */
  collapsar::DateTime temporal;
  Item_result arg0_result_type= args[0]->result_type();
  
  char buff[COLLAPSAR_MAX_LENGTH_DATETIME_AS_STRING];
  String __tmp(buff,sizeof(buff), &my_charset_utf8_bin);
  String *res;
  
  switch (arg0_result_type)
  {
    case DECIMAL_RESULT: 
      /* 
       * For doubles supplied, interpret the arg as a string, 
       * so intentionally fall-through here...
       * This allows us to accept double parameters like 
       * 19971231235959.01 and interpret it the way MySQL does:
       * as a TIMESTAMP-like thing with a microsecond component.
       * Ugh, but need to keep backwards-compat.
       */
    case STRING_RESULT:
      {

        res= args[0]->val_str(&__tmp);
        
        if (! temporal.from_string(res->c_ptr(), res->length()))
        {
          /* 
          * Could not interpret the function argument as a temporal value, 
          * so throw an error and return 0
          */
          my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
          return 0;
        }
      }
      break;
    case INT_RESULT:
      if (temporal.from_int64_t(args[0]->val_int()))
        break;
      /* Intentionally fall-through on invalid conversion from integer */
    default:
      {
        /* 
        * Could not interpret the function argument as a temporal value, 
        * so throw an error and return 0
        */
        null_value= true;

        

        res= args[0]->val_str(&__tmp);

        my_error(ER_INVALID_DATETIME_VALUE, MYF(0), res->c_ptr());
        return 0;
      }
  }
  return (int64_t) ((temporal.months() + 2) / 3);
}
